#include <ESP8266WiFi.h>
#include "ELMduino.h"
#include <SoftwareSerial.h>
#include <LedControl.h>
#include <Adafruit_NeoPixel.h>
#include <FastLED.h>
#define PIN D2
#define BRIGHTNESS 20 // 设置灯光亮度
#define ELM_PORT Serial1

int DIN = D5;
int CS =  D6;
int CLK = D7; 
    LedControl lc=LedControl(DIN,CLK,CS,0);
    byte R[8]={0x7E,0x66,0x66,0x7E,0x70,0x7C,0x6E,0x62};/*"R",0*/
    byte kn[8]={0x42,0x62,0x72,0x5A,0x4E,0x46,0x42,0x00};/*"n",0*/
    byte one[8]={0x18,0x38,0x18,0x18,0x18,0x18,0x7E,0x00};/*"1",0*/
    byte tow[8]={0x7E,0x02,0x02,0x7E,0x40,0x40,0x7E,0x00};/*"2",0*/
    byte sui[8]={0x7E,0x02,0x02,0x3E,0x02,0x02,0x7E,0x00};/*"3",0*/
    byte four[8]={0x08,0x18,0x28,0x48,0x7C,0x08,0x7E,0x00};/*"4",0*/
    byte five[8]={0x7E,0x40,0x40,0x7E,0x02,0x02,0x7E,0x00};/*"5",0*/
    byte six[8]={0x7E,0x40,0x40,0x7E,0x42,0x42,0x7E,0x00};/*"6",0*/
    byte full[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};/*"0",0*/
    byte off[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/*"6",0*/

const char* ssid = "WIFI_OBDII";
const char* password = "your-password";


//IP Adress of your ELM327 Dongle
IPAddress server(192, 168, 0, 10);
WiFiClient client;
ELM327 myELM327;


typedef enum { ENG_RPM,SPEED} obd_pid_states;
obd_pid_states obd_state = ENG_RPM;


float rpm = 0;
float kph = 0;
int Z = 0; 
int x = 0;
float y = 0;
float d = 0;
int j;
int i;
#define NUMPIXELS 10//流水灯数量
 
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
 
void setup()
{
  pixels.begin();
    Serial.begin(230400);
   pixels.setBrightness(BRIGHTNESS); // 设置灯光亮度
  lc.shutdown(0,false);
  lc.setIntensity(0,2);      //Adjust the brightness maximum is 15
  lc.clearDisplay(0); 
  int hue = 0; // 初始化色相值

  // 先熄灭所有灯
  for (int i = 0; i < NUMPIXELS; i++) {
    pixels.setPixelColor(i, 0); // 关闭所有灯
  }
  pixels.show(); // 显示熄灭效果
  delay(100); // 延迟一段时间

  // 依次点亮彩色渐变循环流水灯
  for (int i = 0; i < NUMPIXELS; i++) {
    int pixelColor = pixels.ColorHSV(hue); // 根据色相值获取彩色
    pixels.setPixelColor(i, pixelColor); // 设置每颗灯的颜色
    hue += 655360/180; // 色相值增加，实现彩色渐变循环
    pixels.show(); // 显示灯光效果
    delay(50); // 延迟一段时间
  }
  // Connecting to ELM327 WiFi
  Serial.print("Connecting to ");
  Serial.println(ssid);
  printByte(kn);
  WiFi.mode(WIFI_AP);
  WiFi.begin(ssid);
  // WiFi.begin(ssid, password); //Use this line if your ELM327 has a password protected WiFi

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("Connected to Wifi");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  if (client.connect(server, 35000))
    Serial.println("connected");
  else
  {
    Serial.println("connection failed");
    ESP.reset();
  }

  myELM327.begin(client, true, 2000);
  K0();
}
 

void loop()
{

  switch (obd_state)
  { 
    case ENG_RPM:
    {
      rpm = myELM327.rpm();
      
      if (myELM327.nb_rx_state == ELM_SUCCESS)
      { 
       Z=rpm/1000;
      for (j = 0; j < Z; j++) {
      if(Z<5){pixels.setPixelColor(j, pixels.Color(Z*40, 210/Z, 0)); // 依次点亮灯
        pixels.show(); // 显示灯光效果
     delay(10);
     }
     else {
      MAN();
      pixels.fill(pixels.Color(255, 0, 0), 0, NUMPIXELS);
      pixels.show();
      delay(20); // 等待一段时间
      ONN();
      pixels.clear();
      pixels.show();
      delay(10); // 等待一段时间

     }
  }
  
  for (i = 10 - 1; i >= Z; i--) {
    pixels.setPixelColor(i, 0); // 从右往左依次熄灭
    pixels.show(); // 显示灯光效果
    delay(20);
  }
 
       obd_state = SPEED;
      }
      else if (myELM327.nb_rx_state != ELM_GETTING_MSG)
      {
        myELM327.printError();
        obd_state = SPEED;
      }
      
      break;
    }
    case SPEED:
    {
      kph = myELM327.kph();
      
      if (myELM327.nb_rx_state == ELM_SUCCESS)
      {
      d = rpm/kph;
    if(d>=110&&d<180)
	{
	  K1();
	}
	else if(d>=52&&d<65)
	{
	     K2();
	}
	else if(d>=43&&d<52)
	{
		K3();
	}
	else if(d>=33&&d<41)
	{
	K4();
	}
else if(d>=24&&d<32)
	{
	K5();
	}

else if(d>=10&&d<23)
	{
	K6();
	}
	else{
		K0();

	}

       obd_state = ENG_RPM;

      }
      else if (myELM327.nb_rx_state != ELM_GETTING_MSG)
      {
        myELM327.printError();
        obd_state = ENG_RPM;
      }
      
      break;
    }


}
}

  void K0()
{
   printByte(kn); 
  }

  void K1()
{
   printByte(one);
  }

  void K2()
{
   printByte(tow);
  }

  void K3()
{
    printByte(sui); 
  }

  void K4()
{
   printByte(four);
  }

  void K5()
{
      printByte(five);
  }

  void K6()
{
 printByte(six); 
  }

 void KR()
{
 printByte(R); 
  }

 void MAN()
{
 printByte(full); 
  }

void ONN()
{
 printByte(off); 
  }

void printByte(byte character [])
{
  int i = 0;
  for(i=0;i<8;i++)
  {
    lc.setRow(0,i,character[i]);
  }
}
